package jvlite.dao.createTable;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jvlite.dao.JliteORM.JliteJdbcSupport;
import jvlite.mvc.annotaion.Column;
import jvlite.mvc.annotaion.Constraints;
import jvlite.mvc.annotaion.Table;

import jvlite.util.LogUtil;


public class AutoCreateTable {
	
	private static Map<String, Class<?>> tableEntityMap;
	
	static {
		AutoCreateTable.tableEntityMap = new HashMap<String, Class<?>>();
	}
	
	@SuppressWarnings("unused")
	public static String getCreateSQL(Class<?> c){
		// load class
//			Class<?> c = Class.forName(className);
		// obtain the specific annotation 'table'
		Table table = c.getAnnotation(Table.class); 
		if(table == null){
			LogUtil.info("No Table annotation in class "+ c.getName());
			return null;
		}
		String tableName = table.name();
		AutoCreateTable.tableEntityMap.put(tableName, c);
		if(tableName.length() == 0){
			// if the table name is not defined then give it a default name as the class name
			tableName = c.getName().toUpperCase();
		}
		List<String> columns = new ArrayList<String>();
		
		// iterate all the fields of the class
		for(Field field : c.getDeclaredFields()){
			String columnName = null;
			String columnType = null;
			// get all the annotations of the field exclude that inherited from super class
			// if we need more methods then we should search in the API
			Annotation[] anns = field.getDeclaredAnnotations();
			if(anns.length == 0){
				// if there is not any annotation for the field then ignore it
				continue;
			}else{
				// obtain column annotation
				Column col = (Column) anns[0];
				// assemble the SQL to create the new table
				String name = col.name();
				String type = col.type();
				Integer length = col.length();
				String constraint = getConstraints(col.constraints());
				if(name.length() == 0){
					// obtain default table field name
					columnName = field.getName();
				}else{
					columnName = name;
				}
				if(type.length() == 0){
					// obtain default field type
					columnType = field.getType().toString();
				}else{
					columnType = type;
				}
				if(length == 0){
					// obtain default field length
					length = Types.map.get(type);
					if(length == null){
						throw new RuntimeException("Type cant't be solved :"+type);
					}
				}
				type = Types.getType(type,length);
				columns.add(columnName + " "+ type+constraint);
			}
		}
		if(columns.size() == 0){
			throw new RuntimeException("There is no field in "+c.getName());
		}
		StringBuilder createCommand = new StringBuilder("CREATE TABLE "+tableName +" (");
		for(String column : columns){
			createCommand.append("\n "+column +" ,");
		}
		String createTable = createCommand.substring(0,createCommand.length()-1)+" \n );";
		return createTable;
	}
	
	/**
	 * fetch the constrains
	 * @param con
	 * @return
	 */
	private static String getConstraints(Constraints con){
		String constraints = "";
		if(!con.allowNull()){
			constraints += " NOT NULL";
		}
		if(con.primaryKey()){
			constraints += " PRIMARY KEY";
		}
		if(con.unique()){
			constraints += " UNIQUE ";
		}
		return constraints;
	}
	
	/**
	 * fetch necessary field
	 * @param fields
	 * @return
	 */
	public static List<Field> getNeedField(Field[] fields){
		List<Field> allFileds = new ArrayList<Field>();
		for(Field field : fields){
			// get all the annotations of the field exclude that inherited from super class
			Annotation[] anns = field.getDeclaredAnnotations();
			if(anns.length != 0){
				// if there is not any annotation for the field then ignore it
				allFileds.add(field);
			}
		}
		return allFileds;
	}
	
	public static void generateTable(Class<?> clz){
		Map<String, Class<?>> tableEntityMap = AutoCreateTable.tableEntityMap;
		for (String tableName : tableEntityMap.keySet()) {
			String res = null;
			try {
				res = JliteJdbcSupport.queryBySQL("SHOW TABLES LIKE '"+tableName+"'");
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			if (null == res) {
				String makeTableSQL = AutoCreateTable.getCreateSQL(clz);
				try {
					
					JliteJdbcSupport.executeSQL(makeTableSQL);
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
//		String tableName = null;
//		try {
//			tableName = JdbcTemplate.queryBySQL("SHOW TABLES LIKE 'tbl_exam'");
//		} catch (SQLException e1) {
//			e1.printStackTrace();
//		}
//		if (null == tableName) {
//			String tableSQL = AutoCreateTable.getCreateSQL(ExamVO.class);
//			try {
//				
//				JdbcTemplate.executeSQL(tableSQL);
//			} catch (SQLException e) {
//				e.printStackTrace();
//			}
//		}
	}
	
}